package com.sangmo.fts.authority.filters;

import com.sangmo.boot.framework.common.session.UserSession;
import com.sangmo.boot.framework.common.utils.UnderlineToCamelUtils;
import com.sangmo.fts.authority.meta.ClazzMemberAnn;
import com.sangmo.fts.authority.meta.TeammateAnn;
import com.sangmo.fts.clazz.model.UserClazz;
import com.sangmo.fts.common.authority.EntitySearchContext;
import com.sangmo.fts.common.authority.IAuthorityFilter;
import com.sangmo.fts.common.authority.sql.NativeSearchContext;
import com.sangmo.fts.training.model.Teammate;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;

/**
 * 当是团队成员时，具备读/写权限
 */
public class ClazzMemberFilter implements IAuthorityFilter<ClazzMemberAnn> {
    @Override
    public Class<ClazzMemberAnn> getAnnotation() {
        return ClazzMemberAnn.class;
    }

    @Override
    public SearchFilterResult internalSearchFilter(EntitySearchContext context, ClazzMemberAnn annotation, int usedRight) {
        Root root = context.getRoot();
        CriteriaBuilder cb = context.getCriteriaBuilder();

        Long userId = (Long) UserSession.getUserInterface().getId();

        CriteriaQuery<?> criteriaQuery = cb.createQuery();
        Subquery subquery = criteriaQuery.subquery(Long.class);
        Root memberRoot = subquery.from(UserClazz.class);
        subquery.select(memberRoot.get("id"));

        Predicate p1 = cb.equal(memberRoot.get("clazzId"), root.get(annotation.clazzId()));
        Predicate p2 = cb.equal(memberRoot.get("userId"), userId);
        subquery.where(cb.and(p1, p2));

        return new SearchFilterResult().setPredicate(cb.exists(subquery));
    }

    /*@Override
    public boolean internalFilterCreation(Entity entity, TeammateAnn annotation, int expectedRight) {
        String teamId = (String) BeanUtils.getProperty(entity, annotation.teamId());

        ProjectMemberEntityService projectMemberEntityService = ApplicationUtils.getBean(ProjectMemberEntityService.class);

        Long currentUserId = (Long) UserSession.getUserInterface().getId();
        return projectMemberEntityService.isMemberOrManager(teamId, accountId);
    }*/

    @Override
    public NativeSearchFilterResult internalNativeSearchFilter(NativeSearchContext context, ClazzMemberAnn annotation, int expectedRight) {
        //EXISTS(SELECT 1 FROM ProjectMember x WHERE x.project_id = c.annotation_project_id AND x.account_id = :accountId )

        NativeSearchFilterResult result = new NativeSearchFilterResult();

        String memberTable = UnderlineToCamelUtils.camelToUnderline(UserClazz.class.getSimpleName());
        String memberAlias = context.createAlias();

        String accountVar = context.createVar();
        Long userId = (Long)UserSession.getUserInterface().getId();
        result.getVariables().put(accountVar, userId);

        String subQuery = String.format("SELECT 1 FROM %s AS %s WHERE %s.clazz_id = %s.%s AND %s.user_id = :%s ",
                memberTable,
                memberAlias,
                memberAlias,
                context.getAlias(),
                UnderlineToCamelUtils.camelToUnderline(annotation.clazzId()),
                memberAlias,
                accountVar
        );

        return result.setSql(String.format(" EXISTS (%s) ", subQuery));
    }
}
